import copy
import uuid
import traceback
from dbpool import install, get_connection_exception
from .utils import insert_batch, save_file, insert_batch_onebyone
from inspect import isfunction
# coding:utf8
SAVE_STEP = 20
DB_INSERT_TYPE = 'db_insert'
DB_UPDATE_TYPE = 'db_update'
FILE_TYPE = 'file'
SAVE_TYPE = [
    DB_INSERT_TYPE,
    DB_UPDATE_TYPE,
    FILE_TYPE
]


class HtmlOutputer(object):
    def __init__(self, save_conf):
        self._conf = save_conf
        self.save_conf = copy.deepcopy(self._conf)
        self.datas = []

    def save(self, data, now=False):
        self.save_conf = copy.deepcopy(self._conf)
        if data is None:
            return
        self.datas.append(data)
        if now or len(self.datas) >= SAVE_STEP:
            if self.save_conf['type'] == DB_INSERT_TYPE:
                self.save_to_db()
            if self.save_conf['type'] == DB_UPDATE_TYPE:
                self.db_update()
            elif self.save_conf['type'] == FILE_TYPE:
                self.save_to_file()

    def collect_data(self, data):
        if data is None:
            return
        self.datas.append(data)

    def db_update(self):
        if not self.datas:
            return
        # 将数据取出
        _datas = copy.copy(self.datas)
        self.datas = list()
        update_datas = list()
        if self.save_conf.get('field_conf'):
            for i in _datas:
                _dict = dict()
                for field, conf in self.save_conf['field_conf'].items():
                    if conf['type'] == 'from_parse_field':
                        _dict[field] = i[conf['field']]
                    elif conf['type'] == 'fixed':
                        _dict[field] = conf['field']
                if self.save_conf.get('list_field'):
                    _dict[self.save_conf['list_field']] = list(set(_dict[self.save_conf['list_field']]))
                    for i in _dict[self.save_conf['list_field']]:
                        if not i:
                            continue
                        _dict2 = dict()
                        for k, v in _dict.items():
                            if k != self.save_conf['list_field']:
                                if isinstance(v, list) and len(v) == 1:
                                    _dict2[k] = v[0]
                                elif isinstance(v, str):
                                    _dict2[k] = v
                                elif isfunction(v):
                                    _dict2[k] = v()
                            else:
                                _dict2[k] = i
                        update_datas.append(_dict2)
                else:
                    where = dict()
                    values = dict()
                    _dict2 = dict()
                    for k, v in _dict.items():
                        if isinstance(v, list) and len(v) == 1:
                            _dict2[k] = v[0]
                        elif isinstance(v, str):
                            _dict2[k] = v
                        elif isfunction(v):
                            _dict2[k] = str(v())
                    for k, v in _dict2.items():
                        if k in self.save_conf['update_key']:
                            where[k] = v
                        else:
                            values[k] = v
                    update_datas.append(_dict2)
                    with get_connection_exception(self.save_conf['db_conf']['database']) as db:
                        table = self.save_conf['db_conf']['table']
                        # print(save_datas)
                        db.update(table=table, values=values, where=where)


    def save_to_db(self):
        if not self.datas:
            return
        # 将数据取出
        _datas = copy.copy(self.datas)
        self.datas = list()
        save_datas = list()
        if self.save_conf.get('field_conf'):
            for i in _datas:
                _dict = dict()
                for field, conf in self.save_conf['field_conf'].items():
                    if conf['type'] == 'from_parse_field':
                        _dict[field] = i[conf['field']]
                    elif conf['type'] == 'fixed':
                        _dict[field] = conf['field']
                if self.save_conf.get('list_field'):
                    _dict[self.save_conf['list_field']] = list(set(_dict[self.save_conf['list_field']]))
                    for i in _dict[self.save_conf['list_field']]:
                        if not i:
                            continue
                        _dict2 = dict()
                        for k, v in _dict.items():
                            if k != self.save_conf['list_field']:
                                if isinstance(v, list) and len(v) == 1:
                                    _dict2[k] = v[0]
                                elif isinstance(v, str):
                                    _dict2[k] = v
                                elif isfunction(v):
                                    _dict2[k] = v()
                            else:
                                _dict2[k] = i
                        save_datas.append(_dict2)
                else:
                    _dict2 = dict()
                    for k, v in _dict.items():
                        if isinstance(v, list) and len(v) == 1:
                            _dict2[k] = v[0]
                        elif isinstance(v, str):
                            _dict2[k] = v
                        elif isfunction(v):
                            _dict2[k] = str(v())
                    save_datas.append(_dict2)
        with get_connection_exception(self.save_conf['db_conf']['database']) as db:
            table = self.save_conf['db_conf']['table']
            # print(save_datas)
            insert_batch_onebyone(db, table, save_datas)


    def save_to_file(self):
        _datas = copy.copy(self.datas)
        self.datas = list()
        if self.save_conf.get('file_conf'):
            save_file(_datas, self.save_conf['file_conf']['filepath'])

    def output_html(self):
        fout = open('output.html', 'w', encoding='utf-8')

        fout.write("<html>")
        fout.write("<body>")
        fout.write("<table>")

        # python默认编码：ascii，这里要改成utf-8
        for data in self.datas:
            fout.write("<tr>")
            fout.write("<td>%s</td>" % data['url'])
            fout.write("<td>%s</td>" % data['title'])
            fout.write("<td>%s</td>" % data['summary'])
            fout.write("</tr>")

        fout.write("</table>")
        fout.write("</body>")
        fout.write("</html>")

        fout.close()


